package org.geektimes.rest.client;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;

import javax.ws.rs.HttpMethod;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.InvocationCallback;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;

import org.geektimes.rest.core.DefaultResponse;

import com.fasterxml.jackson.databind.ObjectMapper;

class HttpPostInvocation implements Invocation{
	
    private final URL url;

    private final MultivaluedMap<String, Object> headers;
    
    private final Entity<?> params;
    
	public HttpPostInvocation(URI uri, MultivaluedMap<String, Object> headers, Entity<?> params) throws MalformedURLException {
		this.url = uri.toURL();
		this.headers = headers;
		this.params = params;
	}

	@Override
	public Invocation property(String name, Object value) {
		return this;
	}

	@Override
	public Response invoke() {
		 HttpURLConnection connection = null;
	        try {
	            connection = (HttpURLConnection) url.openConnection();
	            connection.setRequestMethod(HttpMethod.POST);
	            connection.setDoInput(true);
	            connection.setDoOutput(true);
	            setRequestHeaders(connection);
	            ObjectMapper objectMapper = new ObjectMapper();
	            
	            String jsonBody = objectMapper.writeValueAsString(params.getEntity());
	            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
	            writer.append(jsonBody);
	            writer.close();
	            // TODO Set the cookies
	            int statusCode = connection.getResponseCode();
//	            Response.ResponseBuilder responseBuilder = Response.status(statusCode);
	//
//	            responseBuilder.build();
	            DefaultResponse response = new DefaultResponse();
	            response.setConnection(connection);
	            response.setStatus(statusCode);
	            return response;
//	            Response.Status status = Response.Status.fromStatusCode(statusCode);
//	            switch (status) {
//	                case Response.Status.OK:
	//
//	                    break;
//	                default:
//	                    break;
//	            }

	        } catch (IOException e) {
	        }
	        return null;
	}

	@Override
	public <T> T invoke(Class<T> responseType) {
		Response response = invoke();
		return response.readEntity(responseType);
	}

	@Override
	public <T> T invoke(GenericType<T> responseType) {
		Response response = invoke();
		return response.readEntity(responseType);
	}

	@Override
	public Future<Response> submit() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <T> Future<T> submit(Class<T> responseType) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <T> Future<T> submit(GenericType<T> responseType) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <T> Future<T> submit(InvocationCallback<T> callback) {
		// TODO Auto-generated method stub
		return null;
	}
	
	  private void setRequestHeaders(HttpURLConnection connection) {
	        for (Map.Entry<String, List<Object>> entry : headers.entrySet()) {
	            String headerName = entry.getKey();
	            for (Object headerValue : entry.getValue()) {
	                connection.setRequestProperty(headerName, headerValue.toString());
	            }
	        }
	        connection.setRequestProperty("Accept", "application/json");
	        connection.setRequestProperty("Content-type", "application/json");
	    }

}
